#include <iostream>
#include <fstream>
#include <filesystem>
#include <iomanip>
#include <cstring>
#include <ctime>
#include "zip_utils.h"

using namespace std;
namespace fs = filesystem;

int main(int argc, char *argv[]) {
    float time, comp_rate;
    size_t raw_size = 0, comp_size = 0;
    clock_t start = clock();

    string output_path = argv[argc - 1];
    ofstream output(output_path, ios::binary);

    try {
        if (argc == 3) {
            string input_path = argv[1];

            if (fs::is_regular_file(input_path)) { // Single file

                read_load(output, input_path, raw_size, comp_size);

            } else if (fs::is_directory(input_path)) { // A directory

                for (const auto &entry: fs::recursive_directory_iterator(input_path)) {
                    if (entry.is_regular_file())
                        read_load(output, entry.path().string(), raw_size, comp_size, input_path);
                }
            }

        } else if (argc > 3) { // Multiple files, containing "*"
            string program_name = get_relpath(argv[0]);

            for (int i = 1; i < argc - 1; ++i) {
                // Is a file, not the program itself or the output file
                if (fs::is_regular_file(argv[i]) && (argv[i] != program_name) && (argv[i] != output_path)) {
                    string input_path = argv[i];
                    read_load(output, input_path, raw_size, comp_size);
                }
            }

        } else {
            cerr << "Wrong argument!" << endl;
            return EXIT_FAILURE;
        }

    } catch (const runtime_error &e) {
        cerr << e.what() << endl;
        return EXIT_FAILURE;
    }

    output.close();

    // Calculate time and compression rate
    clock_t end = clock();
    time = static_cast<float>(end - start) / CLOCKS_PER_SEC;
    comp_rate = static_cast<float>(comp_size) / static_cast<float>(raw_size);

    // Print messages
    cout << "Finished compressing files." << endl;
    if (time > 0) {
        cout << "Used time : " << time << "s" << endl;
    } else if (time == 0) {
        cout << "Used time : <0.001s" << endl;
    }
    if (comp_rate != -1) {
        cout << "Compression rate : " << fixed << setprecision(2) << comp_rate * 100 << "%" << endl;
    }
    if (comp_rate >= 1) {
        cout << "Warning : This file does not seem suitable for RLE algorithm. Consider using other compression tools."
             << endl;
    }

    return 0;
}
